package com.laworks.urlutils;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.regex.*;
import java.lang.Long;

import org.apache.http.client.methods.HttpGet;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.*;


class ImageDownloader
{

    /**
     * @return the dirPath
     */
    public String getDirPath()
    {
        return dirPath;
    }

    /**
     * @param dirPath the dirPath to set
     */
    public void setDirPath(String dirPath)
    {
        this.dirPath = dirPath;
    }

    public ImageDownloader(String imageUrl)
    {
        this.imageList.add(imageUrl);
        this.dirPath = "/sdcard/DownFile/photo/";
    }

    public ImageDownloader(String imageUrl, String dirPath)
    {
        this.imageList.add(imageUrl);
        this.dirPath = dirPath;
    }

    public ImageDownloader(ArrayList<String> imageList)
    {
        this.imageList.addAll(imageList);
        this.dirPath = "/sdcard/DownFile/photo/";
    }

    public ImageDownloader(ArrayList<String> imageList, String dirPath)
    {
        this.imageList.addAll(imageList);
        this.dirPath = dirPath;
    }



    public Map<String, String> downloadImage()
    {
        //remove duplicate urls;
        imageList = this.uniqueArrayList(imageList);
        for (String imageUrl : imageList)
        {
            try
            {
                String filePath = this.saveImage(imageUrl);
                successMap.put(imageUrl, filePath);
            } catch (Exception e)
            {
                // TODO: handle exception
                failedMap.put(imageUrl, e.getMessage());
            }
        }
        return successMap;
    }
    


    public Map<String, String> getDownloadImageMap()
    {
        return this.successMap;
    }

    public Map<String, String> getFailedImageMap()
    {
        return this.failedMap;
    }

    private void getImageType(HttpResponse response) throws Exception
    {
        Header[] headers = response.getHeaders("Content-Type");
        String contentType = null;
        if (headers.length > 1)
        {
            throw new Exception();
        }
        contentType = headers[0].toString();

        String patternString = "image.(png|jpeg|jpg)";

        Pattern imageFilePatthen = Pattern.compile(patternString,
                Pattern.CASE_INSENSITIVE);

        Matcher matcher = imageFilePatthen.matcher(contentType);

        if (matcher.find())
        {
            String typeString = matcher.group(1);
            if (typeString.equalsIgnoreCase("jpg")
                    || typeString.equalsIgnoreCase("jpeg"))
            {
                fileExtension = ".jpg";
            } else if (typeString.equalsIgnoreCase("png"))
            {
                fileExtension = ".png";
            } else if (typeString.equalsIgnoreCase("gif"))
            {
                fileExtension = ".gif";
            } else if (typeString.equalsIgnoreCase("bmp"))
            {
                fileExtension = ".bmp";
            } else
            {
                throw new Exception();
            }
        }
        else
        {
            throw new Exception();
        }
        return;
    }

    private String saveImage(String imageUrl) throws Exception
    {
        DefaultHttpClient client = new DefaultHttpClient();

        HttpGet request = new HttpGet(imageUrl);
        String fileName;
        try
        {
            response = client.execute(request);
            StatusLine statusLine = response.getStatusLine();
            int reqCode = statusLine.getStatusCode();
            if (reqCode != HttpStatus.SC_OK)
            {
                throw new Exception("Error in response, response code is: " + reqCode);
            }

            this.getImageType(response);

            entity = response.getEntity();
            InputStream inputStream = entity.getContent();

            String timeStamp = Long.toString(Calendar.getInstance()
                    .getTimeInMillis());
            fileName = this.dirPath + timeStamp + this.fileExtension;
            File outputFile = new File(fileName);
            FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
            BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(
                    fileOutputStream);

            byte[] byteArray = new byte[4096];
            int len = inputStream.read(byteArray);
            while (len != -1)
            {
                bufferedOutputStream.write(byteArray, 0, len);
                len = inputStream.read(byteArray);
            }
            bufferedOutputStream.flush();
            bufferedOutputStream.close();
        } catch (Exception e)
        {
            throw e;
        }

        return fileName;
    }
    
    private ArrayList<String> uniqueArrayList(ArrayList<String> list)
    {
        ArrayList<String> result = new ArrayList<String>();
        HashSet<String> tempSet = new HashSet<String>();
        for(String element : list)
        {
            if(!tempSet.add(element)) continue;
            result.add(element);
        }
        return result;
    }
    
    private ArrayList<String> imageList = new ArrayList<String>();
    private String dirPath;
    private String fileExtension;

    private HttpResponse response;
    private HttpEntity entity;

    private Map<String, String> successMap = new HashMap<String, String>();
    private Map<String, String> failedMap = new HashMap<String, String>();

}

public class UrlUtil
{

    public static void main(String[] args)
    {
        // TODO Auto-generated method stub
        ArrayList<String> imageList = new ArrayList<String>();
        for (int i = 1; i < 10; i++)
        {
            String url = "http://127.0.0.1/test/0" + i + ".jpg";
            imageList.add(url);
        }
        for (int i = 1; i < 10; i++)
        {
            String url = "http://127.0.0.1/test/0" + i + ".jpg";
            imageList.add(url);
        }
        
        imageList.add("test");
        imageList.add("test22");
        ImageDownloader idownloader = new ImageDownloader(imageList, "/home/leo/temp/");
        Map<String, String> result = idownloader.downloadImage();
        Map<String, String> failed = idownloader.getFailedImageMap();
        Iterator iter = result.entrySet().iterator();
        while (iter.hasNext())
        {
            Map.Entry<String, String> entry = (Map.Entry<String, String>)iter.next();
            String imageUrl = entry.getKey();
            String fileName = entry.getValue();
            System.out.println(String.format("%s : %s", imageUrl, fileName));
        }
        
        iter = failed.entrySet().iterator();
        while (iter.hasNext())
        {
            Map.Entry<String, String> entry = (Map.Entry<String, String>)iter.next();
            String imageUrl = entry.getKey();
            String fileName = entry.getValue();
            System.out.println(String.format("%s : %s", imageUrl, fileName));
        }
        return;
    }
    
    
}
